package models

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

type Operators struct {
	ID              int       `gorm:"primary_key" json:"id"`
	UserId          int       `gorm:"default:0" json:"user_id"`
	PlacePartnerId  int       `gorm:"default:0" json:"manage_center"`
	BusinessLicense string    `gorm:"default:''" json:"business_license"`
	ProvinceId      int       `gorm:"default:0" json:"province"`
	CityId          int       `gorm:"default:0" json:"city"`
	AreaId          int       `gorm:"default:0" json:"area"`
	Title           string    `gorm:"default:''" json:"title"`
	Name            string    `gorm:"default:''" json:"username"`
	Phone           string    `gorm:"default:''" json:"phone"`
	IdCard          string    `gorm:"default:''" json:"id_card"`
	BankCardNo      string    `gorm:"default:''" json:"bank_card_no"`
	BankCardName    string    `gorm:"default:''" json:"bank_card_name"`
	BankName        string    `gorm:"default:''" json:"bank_name"`
	BankBranch      string    `gorm:"default:''" json:"bank_branch"`
	SalesmanCount   int       `gorm:"default:0" json:"salesman_count"`
	UserCount       int       `gorm:"default:0" json:"user_count"`
	VipCount        int       `gorm:"default:0" json:"vip_count"`
	CreatedAt       time.Time `gorm:"default:''" json:"created_at"`
	UpdatedAt       time.Time `gorm:"default:''" json:"updated_at"`
	Status          int       `gorm:"default:0" json:"status"`
	Examine         int       `gorm:"default:0" json:"examine"`
	ExaminedAt      time.Time `gorm:"default:''" json:"examined_at"`
	AgencyFee       float64   `gorm:"default:0" json:"agency_money"`
	RefereeName     string    `gorm:"default:''" json:"referee_name"`
	RefereePhone    string    `gorm:"default:''" json:"referee_phone"`
	IdCardFront     string    `gorm:"default:''" json:"id_card_front"`
	IdCardBack      string    `gorm:"default:''" json:"id_card_back"`
}

func (o *Operators) TableName() string {
	return "operators"
}

func (o *Operators) Insert() bool {
	err := DB.Create(o).Error
	if err != nil {
		return false
	}
	return true
}

func (o *Operators) Update(id int) bool {
	err := DB.Model(o).Where("id=?", id).Update(o).Error
	if err != nil {
		return false
	}
	return true
}

func OperatorsList(page int, limit int, c *gin.Context) (interface{}, *Paginator) {
	var o []*struct {
		ID            int       `json:"id"`
		UserId int 	`json:"-"`
		Title         string    `json:"title"`
		Name          string    `json:"name"`
		Phone string `json:"phone"`
		AgencyFee     float64   `json:"agencyMoney"`
		SalesmanCount int       `json:"salesmanNum"`
		VipCount      int       `json:"vipNum"`
		UserCount     int       `json:"userNum"`
		CreatedAt     time.Time `json:"createdAt"`
		Status        int       `json:"state"`
		Examine      int	`json:"examine"`
	}

	m := DB.Table("operators as o").Select("o.id,o.user_id,o.title,o.name,o.phone,o.agency_fee,s.salesman_count,u.user_count, o.created_at,o.status,o.examine").
		Joins("left join (select count(id) as salesman_count,operator_id from users where type=3 group by operator_id) as s on s.operator_id=o.user_id").
		Joins("left join (select count(id) as user_count,operator_id from users where type=4 group by operator_id) as u on u.operator_id=o.user_id")

	if state, isExist := c.GetQuery("state"); isExist && state != "" {
		m = m.Where("status=?", state)
	}
	if area, isExist := c.GetQuery("area"); isExist && area != "" {
		var id int
		err := DB.Table("places").Select("`id`").Where("o.name like ?", "%"+area+"%").Where("o.level=1").Row().Scan(&id)
		if err != nil {
			fmt.Println(err)
		}
		m = m.Where("o.province=?", id)
	}
	if startTime, isExist := c.GetQuery("begin_time"); isExist && startTime != "" {
		m = m.Where("o.created_at > ?", startTime)
	}
	if endTime, isExist := c.GetQuery("end_time"); isExist && endTime != "" {
		m = m.Where("o.created_at < ?", endTime)
	}
	if phone, isExist := c.GetQuery("phone"); isExist && phone != "" {
		m = m.Where("o.phone=?", phone)
	}
	var count int
	m.Count(&count)
	paginate := NewPage(page, limit, count)
	m.Scan(&o)
	for _, i := range o {
		if i.Examine == 0 {
			i.SalesmanCount = 0
			i.UserCount = 0
			i.VipCount = 0
			continue
		}
		var n int
		DB.Table("user_grade").Where("user_id in (SELECT id from users where operator_id=?)", i.UserId).Count(&n)
		i.VipCount = n
	}
	return &o, &paginate
}

func GetOperatorById(id int) *Operators {
	var oo Operators
	DB.Model(Operators{}).Where("id=?", id).First(&oo)
	return &oo
}

func (o *Operators) Recharges(c *gin.Context, page int, limit int) (interface{}, *Paginator){
	var res []*struct{
		ID int `json:"id"`
		Title string `json:"title"`
		UserId int `json:"user_id"`
		AllMoney float64 `json:"all_money"`
		LastMonthMoney float64 `json:"last_month_money"`
		CurrentMoney float64 `json:"current_money"`
		Admin string `json:"admin"`
		Phone string `json:"phone"`
	}
	model := DB.Table("operators as o").
		Select("o.id,o.title,o.phone,o.user_id,IFNULL(bonus.money,0) as all_money,IFNULL(bonus_sub.money,0) as last_month_money,IFNULL(bonus_to.money,0) as current_money").
		Joins("left join (select user_id, sum(money) as money from user_place_partner_bonus_count where income_type=1 group by user_id) as bonus on bonus.user_id=o.user_id").
		Joins("left join (select user_id, sum(money) as money from user_place_partner_bonus_count where income_type=1 and PERIOD_DIFF(date_format(now(), '%Y%m'),date_format(created_at,'%Y%m')) = 1 group by user_id) as bonus_sub on bonus_sub.user_id=o.user_id").
		Joins("left join (select user_id, sum(money) as money from user_place_partner_bonus_count where income_type=1 and DATE_FORMAT(created_at,'%Y%m')=DATE_FORMAT(CURDATE(), '%Y%m') group by user_id) as bonus_to on bonus_to.user_id=o.user_id")

	var count int
	model.Count(&count)
	paginate := NewPage(page, limit, count)
	model.Scan(&res)

	return res, &paginate
}

func (o *Operators) RechargesDetail(c *gin.Context, page int, limit int) interface{}  {
	id := c.Query("id")
	var o1 Operators
	DB.Model(o).Where("id=?", id).First(&o1)

	var total float64
	var vipTotal float64
	var vipToday float64
	var eTotal float64
	var lastMonthTotal float64
	var currMonthTotal float64
	_ = Table("user_operators_bonus_count").Select("sum(money)").Where("user_id=?", o1.UserId).Where("income_type=1").Row().Scan(&total)
	_ = Table("user_operators_bonus_count").Select("sum(money)").Where("income_type=1").Where("user_id=?", o1.UserId).Where("type=1").Row().Scan(&vipTotal)
	_ = Table("user_operators_bonus_count").Select("sum(money)").Where("user_id=?", o1.UserId).Where("income_type=1").Where("type=1").Where("to_days(created_at)=to_days(now())").Row().Scan(&vipToday)
	_ = Table("user_operators_bonus_count").Select("sum(money)").Where("income_type=1").Where("user_id=?", o1.UserId).Where("type=2").Row().Scan(&eTotal)
	//上月奖励金
	_ = Table("user_operators_bonus_count").Select("sum(money)").Where("income_type=1").Where("user_id=?", o1.UserId).Where("PERIOD_DIFF(date_format(now(), '%Y%m'),date_format(created_at,'%Y%m')) = 1").Row().Scan(&lastMonthTotal)
	//当月
	_ = Table("user_operators_bonus_count").Select("sum(money)").Where("income_type=1").Where("user_id=?", o1.UserId).Where("DATE_FORMAT(created_at,'%Y%m')=DATE_FORMAT(CURDATE(), '%Y%m')").Row().Scan(&currMonthTotal)

	return map[string]float64{
		"total":total,
		"vip_total": vipTotal,
		"e_total" : eTotal,
		"vip_today": vipToday,
		"last_month_total": lastMonthTotal,
		"curr_month_total": currMonthTotal,
	}
}

func (o *Operators) RechargesVipList(c *gin.Context, page int, limit int) (interface{}, *Paginator)  {
	id := c.Query("id")
	var o1 Operators
	DB.Model(o).Where("id=?", id).First(&o1)
	var res []*struct{
		UserName string	`json:"user_name"`
		Phone string `json:"phone"`
		Relation string `json:"relation"`
		PayTime time.Time `json:"pay_time"`
		VipFeeConfigComment string `json:"vip_level"`
		Money float64 `json:"money"`
		TMoney float64 `json:"t_money"`
		TTime time.Time `json:"t_time"`
	}
	model := Table("user_commission_details as ucd").
		Select("c.user_name,u.phone,ucd.relation,ur.pay_time,ur.vip_fee_config_comment,ur.money,ucd.money as t_money,ucd.created_at as t_time").
		Joins("left join user_recharges as ur on ur.out_trade_no=ucd.out_trade_no").
		Where("ucd.relation_id=?", o1.UserId).
		Joins("left join users u on u.id=ucd.user_id").
		Joins("left join cards c on c.user_id=ucd.user_id")

	if startTime, isExist := c.GetQuery("begin_time"); isExist && startTime != "" {
		model = model.Where("ucd.created_at > ?", startTime)
	}
	if endTime, isExist := c.GetQuery("end_time"); isExist && endTime != "" {
		model = model.Where("ucd.created_at < ?", endTime)
	}
	if phone, isExist := c.GetQuery("phone"); isExist && phone != "" {
		model = model.Where("u.phone=?", phone)
	}
	if vip, isExist := c.GetQuery("vip"); isExist && vip != "" {
		model = model.Where("ur.vip_fee_config_comment=?", vip)
	}

	var count int
	model.Count(&count)
	paginate := NewPage(page, limit, count)
	model.Offset(paginate.Offset).Limit(paginate.Limit).Scan(&res)
	return &res, &paginate
}


func (o *Operators) RechargesEList(c *gin.Context, page int, limit int) (interface{}, *Paginator) {
	id := c.Query("id")
	var o1 Operators
	DB.Model(o).Where("id=?", id).First(&o1)
	var res []*struct{
		Name string `json:"name"`
		User string `json:"user"`
		Phone string `json:"phone"`
		Money float64 `json:"money"`
		RMoney float64 `json:"r_money"`
		PayTime time.Time `json:"pay_time"`
	}
	model := Table("user_operators_bonus_count as uobc").
		Select("e.name,es.name as user,es.phone,er.money,uobc.money as r_money,er.pay_time").
		Joins("left join enterprise_recharge_fenxiao_queue as eq on eq.id=uobc.relation_id").
		Joins("left join enterprise_recharges er on er.out_trade_no=eq.out_trade_no").
		Joins("left join enterprise e on e.id=er.enterprise_id").
		Joins("left join enterprise_staff es on es.id=er.staff_id").
		Where("uobc.user_id=?",o1.UserId)

	if startTime, isExist := c.GetQuery("begin_time"); isExist && startTime != "" {
		model = model.Where("uobc.created_at > ?", startTime)
	}
	if endTime, isExist := c.GetQuery("end_time"); isExist && endTime != "" {
		model = model.Where("uobc.created_at < ?", endTime)
	}
	if phone, isExist := c.GetQuery("phone"); isExist && phone != "" {
		model = model.Where("es.phone=?", phone)
	}

	var count int
	model.Count(&count)
	paginate := NewPage(page, limit, count)
	model.Offset(paginate.Offset).Limit(paginate.Limit).Scan(&res)
	return &res, &paginate
}
func (m *Operators) Cash(c *gin.Context, page int, limit int) (interface{}, *Paginator) {
	id := c.Query("id")
	var res []*struct{
		ID int `json:"id"`
		Bank string `json:"bank"`
		BankCardName string `json:"bank_card_name"`
		BankCardNo string `json:"bank_card_no"`
		Money float64 `json:"money"`
		PayTime time.Time `json:"pay_time"`
		Status int `json:"status"`
	}
	model := Table("bonus_cash").Where("target_id=?", id).Where("type=3")

	var count int
	model.Count(&count)
	paginate := NewPage(page, limit, count)
	model.Offset(paginate.Offset).Limit(paginate.Limit).Scan(&res)
	return &res, &paginate
}